﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindowViewModel.cs" company="ICodeFrog">
//   Max B.
// </copyright>
// <summary>
//   The main window view model.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace FFMPEG_MKV2MP4
{
    using System.Configuration;
    using System.IO;
    using System.Windows;
    using System.Windows.Input;

    using Ookii.Dialogs.Wpf;

    /// <summary>
    /// The main window view model.
    /// </summary>
    public class MainWindowViewModel : ViewModelBase
    {
        #region Constants

        /// <summary>
        /// The key in the App.config to get the path to FFMPEG
        /// </summary>
        private const string PathToFFMPEGSettingKey = "PathToFFMPEG";

        #endregion

        #region Fields

        /// <summary>
        /// The configuration.
        /// </summary>
        private readonly Configuration configuration;

        /// <summary>
        /// The path to destination.
        /// </summary>
        private string pathToDestination;

        /// <summary>
        /// The path to ffmpeg.
        /// </summary>
        private string pathToFFMPEG;

        /// <summary>
        /// The path to source.
        /// </summary>
        private string pathToSource;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
        /// </summary>
        public MainWindowViewModel()
        {
            this.configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            string ffmpegPath = this.configuration.AppSettings.Settings[PathToFFMPEGSettingKey].Value;

            if (File.Exists(ffmpegPath))
            {
                this.PathToFFMPEG = ffmpegPath;
            }
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets the exit application command.
        /// </summary>
        public ICommand ExitApplication
        {
            get
            {
                return new DelegatedCommand(() => Application.Current.Shutdown());
            }
        }

        /// <summary>
        /// Gets or sets the path to destination.
        /// </summary>
        public string PathToDestination
        {
            get
            {
                return this.pathToDestination;
            }

            set
            {
                this.pathToDestination = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the path to ffmpeg.
        /// </summary>
        public string PathToFFMPEG
        {
            get
            {
                return this.pathToFFMPEG;
            }

            set
            {
                this.pathToFFMPEG = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the path to source.
        /// </summary>
        public string PathToSource
        {
            get
            {
                return this.pathToSource;
            }

            set
            {
                this.pathToSource = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets the set path to destination.
        /// </summary>
        public ICommand SetPathToDestination
        {
            get
            {
                return new DelegatedCommand(() => { this.PathToDestination = this.SetDestinationFile(); });
            }
        }

        /// <summary>
        /// Gets the set path to ffmpeg.
        /// </summary>
        public ICommand SetPathToFFMPEG
        {
            get
            {
                return new DelegatedCommand(
                    () =>
                        {
                            this.PathToFFMPEG = this.GetFFMPEG();
                            this.configuration.AppSettings.Settings[PathToFFMPEGSettingKey].Value = this.PathToFFMPEG;
                            this.configuration.Save(ConfigurationSaveMode.Modified);
                        });
            }
        }

        /// <summary>
        /// Gets the set path to source file.
        /// </summary>
        public ICommand SetPathToSource
        {
            get
            {
                return new DelegatedCommand(
                    () =>
                        {
                            this.PathToSource = this.GetSourceFile();
                            this.PathToDestination = this.PathToSource.Replace("mkv", "mp4");
                        });
            }
        }

        /// <summary>
        /// Gets the start conversion command.
        /// </summary>
        public ICommand StartConversion
        {
            get
            {
                return new DelegatedCommand(this.BeginConversion);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Starts the conversion.
        /// </summary>
        private void BeginConversion()
        {
            if (!string.IsNullOrEmpty(this.PathToFFMPEG) && !string.IsNullOrEmpty(this.PathToSource))
            {
                if (string.IsNullOrEmpty(this.PathToDestination))
                {
                    this.PathToDestination =
                        this.PathToSource.Substring(this.PathToSource.LastIndexOf('\\') + 1).Replace("mkv", "mp4");
                }

                var cmdHandle = new CMDHandle();

                cmdHandle.ExecuteCommand(
                    string.Format("\"{0}\"", this.PathToFFMPEG), 
                    string.Format(
                        "-i \"{0}\" -acodec copy -vcodec copy \"{1}\"", 
                        this.PathToSource, 
                        this.PathToDestination));
            }
        }

        /// <summary>
        /// Gets the path to ffmpeg.
        /// </summary>
        /// <returns>
        /// The full path with filename to ffmpeg or an empty string if not located.
        /// </returns>
        private string GetFFMPEG()
        {
            var fileDialog = new VistaOpenFileDialog();
            fileDialog.Filter = "exe file (*.exe)|*.exe";

            bool? succeed = fileDialog.ShowDialog();

            if (succeed != null && fileDialog.CheckFileExists)
            {
                return fileDialog.FileName;
            }

            return string.Empty;
        }

        /// <summary>
        /// Gets the source file to use.
        /// </summary>
        /// <returns>
        /// The full path with filename to the source file or an empty string if not located.
        /// </returns>
        private string GetSourceFile()
        {
            var fileDialog = new VistaOpenFileDialog();
            fileDialog.Filter = "mkv file (*.mkv)|*.mkv";

            bool? succeed = fileDialog.ShowDialog();

            if (succeed != null && fileDialog.CheckFileExists)
            {
                return fileDialog.FileName;
            }

            return string.Empty;
        }

        /// <summary>
        /// The set destination file.
        /// </summary>
        /// <returns>
        /// The full path with filename to the destination file or an empty string if not located.
        /// </returns>
        private string SetDestinationFile()
        {
            var saveFileDialog = new VistaSaveFileDialog();

            saveFileDialog.Filter = "mp4 file (*.mp4)|*.mp4";

            saveFileDialog.FileName = this.PathToDestination;

            // saveFileDialog.AddExtension = true; <- Doesn't seem to work?
            bool? succeed = saveFileDialog.ShowDialog();

            if (succeed != null && !saveFileDialog.CheckFileExists)
            {
                return saveFileDialog.FileName.EndsWith(".mp4")
                           ? saveFileDialog.FileName
                           : saveFileDialog.FileName + ".mp4";
            }

            return string.Empty;
        }

        #endregion
    }
}